/***************************************************************************
 *   Copyright (C) 2008 by Łukasz Spintzyk   *
 *   lukasz.spintzyk@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "digital_oscilloscope.h"
#include "display.h"


//stan urz�dzenia wy�wietlany na Ekranie informacyjnym
uint8_t DEV_state=0;//! State of device


upoint8_t cursor1={0,0};//! First cursor co-ordinates
upoint8_t cursor2={0,0};//! Second cursor co-ordinates

uint8_t ch1Pos=DDATA_AREA_SIZE_H/2;     //!GND level of channel 1 on screen display
uint8_t ch2Pos=DDATA_AREA_SIZE_H/2;     //!GND level of channel 2 on screen display
uint8_t chAddPos=DDATA_AREA_SIZE_H/2;   //!GND level of ADD=CH1+CH2 channel on screen display
uint8_t chSubPos=DDATA_AREA_SIZE_H/2;   //!GND level of SUB=CH1-CH2 channel on screen display
uint8_t adjustFreq;//! Value which changes time base period


prog_uint8_t sampleNum[TIME_OPT_NUM]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
prog_uint16_t timeValue[TIME_OPT_NUM]={10,20,50,100,200,500,1,2,5,10,20,50,100,200,500,1};
const char * timeText[TIME_OPT_NUM]={" 10us"," 20us"," 50us","100us","200us","500us","  1ms","  2ms","  5ms"," 10ms"," 20ms"," 50ms","100ms","200ms","500ms","   1s"};

prog_uint16_t voltValue[VOLT_OPT_NUM]={2,20,40,80,100,150, 200,400};
const char * voltText[VOLT_OPT_NUM]={"  2mV"," 20mV"," 40mV"," 80mV","100mV","150mV","200mV","400mV"};


prog_uint8_t stab[VOLT_OPT_NUM]={
    (1<<STA1) | (1<<STA0) | (0<<STB1) | (0<<STB0) | 0x00,
    (1<<STA1) | (1<<STA0) | (0<<STB1) | (1<<STB0) | 0x00,
    (1<<STA1) | (1<<STA0) | (1<<STB1) | (0<<STB0) | 0x00,
    (1<<STA1) | (0<<STA0) | (1<<STB1) | (0<<STB1) | 0x00,
    (1<<STA1) | (1<<STA1) | (1<<STB0) | (1<<STB1) | 0x00,
    (0<<STA0) | (1<<STA1) | (1<<STB0) | (1<<STB1) | 0x00,
    (1<<STA0) | (0<<STA1) | (1<<STB0) | (1<<STB1) | 0x00,
    (0<<STA0) | (1<<STA1) | (1<<STB0) | (0<<STB1) | 0x00,
};//! State of control lines STAx and STBx

int8_t curTimeOpt=TIME_OPT_NUM-1;//! actual index of time div-values array
int8_t curVoltOpt=VOLT_OPT_NUM-1;//! actual index of voltage div-values array



int main(void){


    initDevice();
    drawGrid(0x0000);
            
    /* TESTING CODE
    runADC_AKey(true);  
    display_text_PGM(PSTR("ADC_AKEY"),0,3);
    display_text_PGM(PSTR("TIMER INVOKE"),0,6);
    */

    while(1){
            /* TESTING CODE
                    if (ADC_conversion&(1<<ADC_AKEY)) {
                    upoint8_t pkt={5,4};
                    display_text_PGM(PSTR("          "),5,4);
                    displayBinaryValue(pkt,(uint8_t)adc_key,10);
                    _delay_ms(100.0);
                    }

                    upoint8_t pkt2={5,7};
                    display_text_PGM(PSTR("        "),5,7);
                    displayBinaryValue(pkt2,time,10);
            */

        uint8_t bstate=checkButtons();/// read user action
        if (bstate || (ADC_conversion&(1<<ADC_AKEY))) {

            if (bstate&(1<<SELECT_KEY)) 
                selectClicked();
            if (bstate&(1<<SET_KEY)){
                if (setFunction){
                    setNum++;
                    if (setNum==1) 
                        //! mark that user pressed SET and it is possible to change option.--cursor is blinking
                        showTextCursor(true,8,true,textCursorPos.x,textCursorPos.y);
                    else if (setNum==2) {
                        //! Mark that user turned off changing option --cursor is not blinking
                        showTextCursor(true,1,false,textCursorPos.x,textCursorPos.y);
                        runADC_AKey(false); //! turn off adc conversion of value of analog key
                        setNum=0;
                    }
                }
            }
            if (setFunction && setNum){
                //! if an option in menu is selected and modifyable(Set pressed one time) then change value of it.
                if (bstate&(1<<UP_KEY)) setFunction(1,false);

                if (bstate&(1<<DOWN_KEY)) setFunction(-1,false);

                if (ADC_conversion&(1<<ADC_AKEY)) {
                    setFunction(adc_key,true);
                    ADC_conversion&=(uint8_t)~(1<<ADC_AKEY);//current value is used off
                }
            }

            _delay_ms(60.0);//! wait until posble noise on keyboard bus disappear
        }
    }

} 



/*! Initializes all device modules
 */
void initDevice(){
//!\todo  Finish this function, don't forget about ADC converters and LCD
    _delay_ms(10.0);
     //! \warning attention for -VEE of driving lcd voltage.
    PORT(_VEE_CUT_PORT)&=~(1<<_VEE_CUT_PIN); //set VEE_CUT_PIN =0  -ee
    DDR(_VEE_CUT_PORT)|=(1<<_VEE_CUT_PIN);  //set VEE_CUT_PIN as output, 
    
    
    getTime=getTimeFromTimer;		//! choose time generator from timer
    setFunction=NULL;
    DDR(KEYBOARD)&=~(1<<UP_KEY | 1<<DOWN_KEY | 1<<SELECT_KEY | 1<<SET_KEY); //! set 4bits as input 
    PORT(KEYBOARD)|=1<<UP_KEY | 1<<DOWN_KEY | 1<<SELECT_KEY | 1<<SET_KEY;
    
    //set control port pins as output
    uint8_t variable;    
    memcpy_P(&variable, &stab[curTimeOpt], sizeof(uint8_t));//read data from table placed in rom
    
    DDR(CONTROL)&=(uint8_t)~STAB_MASK;
    PORT(CONTROL)&=(uint8_t)STAB_MASK;
    PORT(CONTROL)|=variable;
    

    lcd_init(0x1800,0x0000,40,40);
    drawInfo();
    

    //set ADC_CS as output
    DDR(LCD_CONTROL)|=(1<<ADC_CS);
    PORT(LCD_CONTROL)|=(1<<ADC_CS);
    
    adc_init();
   // initTimer1();
   // sei();
}
